#!/usr/bin/python
# -*- coding: utf-8 -*-

from trivmoo.utils.decorators import singleton
import unittest

# Subclassing a singleton is not often used.
# You can find many sample in python on the internet.
# Most of them are very complicated and, I think, not very usefull.

# I propose this simple and not error prone solution
# . create a classic base class containing your code
# . create a singleton class using the "singleton" decorator

# the base class
class MyBaseClass(object):
    def get_string(self):
        return "MyBaseClass"

# the base singleton 
@singleton
class MySingleton(MyBaseClass):
    pass

# the subclassing singleton
@singleton
class MyChildSingleton(MyBaseClass):
    def get_string(self):
        return MyBaseClass.get_string(self) + " + MyChildClass"
    
# you can even use multi-inheritance
class MyBaseClass2(object):
    def get_string(self):
        return "MyBaseClass2"

@singleton  
class MyMultiInheritanceSingleton(MyBaseClass, MyBaseClass2):
    def get_string(self):
        return MyBaseClass.get_string(self) + " + " + MyBaseClass2.get_string(self)

class TestSingleton(unittest.TestCase):
    def test_creation(self):
        """TestSingleton: base singleton"""
        oo1 = MySingleton()
        oo2 = MySingleton()
        oo3 = MySingleton()        
        self.assertEqual(oo1, oo2)
        self.assertEqual(oo1, oo3)
        self.assertEqual(oo3, oo2)
        
    def test_inherited(self):
        """TestSingleton: inherited singleton"""
        oo1 = MyChildSingleton()
        oo2 = MyChildSingleton()
        oo3 = MyChildSingleton()        
        self.assertEqual(oo1, oo2)
        self.assertEqual(oo1, oo3)
        self.assertEqual(oo3, oo2)
        self.assertEqual(oo1.get_string(), "MyBaseClass + MyChildClass")
        
    def test_multi_inheritance(self):
        """TestSingleton: multi inherited singleton"""
        oo1 = MyMultiInheritanceSingleton()
        oo2 = MyMultiInheritanceSingleton()
        oo3 = MyMultiInheritanceSingleton()        
        self.assertEqual(oo1, oo2)
        self.assertEqual(oo1, oo3)
        self.assertEqual(oo3, oo2)
        self.assertEqual(oo1.get_string(), "MyBaseClass + MyBaseClass2")


if __name__ == "__main__":
    unittest.main()